home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / asm_n_z.zip / SPRITES2.ASM < prev    next >
Assembly Source File  |  1986-05-27  |  21KB  |  615 lines

  1. ;
  2. ; *** Listing 2 ***
  3. ;
  4. ;These routines produce the effect of hardware sprites in software
  5. ; on IBM PC compatible computers. They put objects onto the screen
  6. ; in a manner which preserves the background, and produces no
  7. ; undesirable fringe or overlap effects. Operations which affect
  8. ; video buffer memory are performed as much as possible during
  9. ; video non-display periods to avoid other undesirable effects.
  10. ;
  11. ; Entry points and parameters:
  12. ;
  13. ;   Initialize - Sets the background buffer address to be used to erase
  14. ;    objects, resets internal flags and queue, and on EGAs
  15. ;    sets up the use of the vertical interrupt to drive the
  16. ;    drawing routines.
  17. ;
  18. ;    Inputs    - AX holds paragraph address of background buffer.
  19. ;    Outputs - None.
  20. ;
  21. ;   Terminate  - Resets the EGA vertical interrupt hardware and vector
  22. ;
  23. ;    Inputs    - None.
  24. ;    Outputs - None.
  25. ;
  26. ;   Object_services - Sets X,Y and Form address for a given object
  27. ;    to be drawn, and activates or deactivates the object.
  28. ;
  29. ;    Inputs    - CX holds X position in bytes (0-79) of upper
  30. ;           left hand corner of object. 0 is leftmost.
  31. ;        - BX holds Y position in lines (0-198) 0 is top.
  32. ;           BX must be even! Objects cannot start on odd lines.
  33. ;           Objects must also be an even number of lines high.
  34. ;        - DI holds object number. Higher numbered objects
  35. ;           will appear to be in front of lower numbered
  36. ;           objects when they overlap.
  37. ;        - SI holds the offset in the code segment of the form
  38. ;           to be drawn for the object. A value of 0ffffh means
  39. ;           that the object is to be erased, then ignored.
  40. ;           Forms must be in the following format:
  41. ;
  42. ;              byte 0 - height in lines (h)
  43. ;              byte 1 - width in bytes  (w)
  44. ;              followed by w X h (mask word, image word) pairs.
  45. ;
  46. ;    Outputs - None.
  47. ;
  48. ;    Registers - All are saved, except flags
  49. ;
  50. ;    Warning - No bounds checking is done. X,Y or object numbers
  51. ;           out of range can send your program into hyperspace.
  52. ;
  53. ;   Put_objects_on_screen - This routine should be called by a program
  54. ;    running on a CGA to put the objects on the screen. It must be
  55. ;    far-called as if it were an interrupt routine. For example:
  56. ;
  57. ;               pushf
  58. ;               call far ptr put_objects_on_screen
  59. ;
  60. ;    For best results this routine should be called immediately
  61. ;     upon the sensing of vertical retrace.
  62. ;
  63. ;    Inputs    - None.
  64. ;    Outputs - None.
  65. ;
  66. ; Vert_int_modulo_count - This memory word is incremented each time
  67. ;   the objects are put into the screen map. On EGAs it can be used
  68. ;   to synchronize a program to the constant time base provided by
  69. ;   the vertical interrupt.
  70. ;
  71. ;The flag below must be set properly before assembling this program
  72. ;
  73. ega    equ  0         ;1 to assemble for Enhanced Graphics Adapter
  74.              ;0 to assemble for Color Graphics Adapter
  75. cga    equ  (ega xor 1) ;the opposite status of ega
  76. ;
  77. bios_data_segment segment at 40h    ;BIOS keeps its data at 400h;
  78.     org    63h            ;at 463h is a word that holds
  79. bios_crtc_base_address    dw    ?    ; the CRT controller's base
  80. bios_data_segment ends            ; address
  81. ;
  82. ;
  83. cseg    segment para public 'cseg'
  84.     assume    cs:cseg,ds:cseg,es:nothing
  85.     public    initialize,terminate,object_services
  86.     public    put_objects_on_screen,vert_int_modulo_count
  87. ;
  88. ;Memory for the parameters used to keep track of objects is reserved
  89. ; below. Many of the parameters stored are very code specific so that
  90. ; the size and number of objects which could be processed during
  91. ; vertical non-display time could be maximized.
  92. ;
  93. number_of_objects equ    3  ;this should be set to the maximum number
  94.                ; of objects or priorities which will
  95.                ; need to be kept track of at one time.
  96. ;
  97. queue label word
  98. ;
  99. draw_screen_offset    dw ?  ;offset in screen memory buffer of upper
  100.                   ; left hand corner of object. 0ffffh if
  101.                   ; object is to be ignored.
  102. dist_to_odd_scan_line    dw ?  ;distance from end of object on an even
  103.                   ; scan line to the start of the object
  104.                   ; on the next (odd) scan line
  105. dist_to_even_scan_line    dw ?  ;distance from end of object on an odd
  106.                   ; scan line to the start of the object
  107.                   ; on the next (even) scan line
  108. ;
  109. erase_parms label word
  110. ;
  111. erase_width         dw ?  ;the object's screen image width in words
  112. erase_entry_point    dw ?  ;the address of the inline code to do erase
  113. erase_screen_offset  dw ?  ;the address where object was last drawn
  114.                ; 0ffffh if object is not to be erased.
  115. erase_image_offset   dw ?  ;used to determine if need to erase when
  116.                ; object is in old position
  117. ;
  118. length_of_erase_parms equ $-erase_parms
  119. ;
  120. draw_col_entry_point dw ?  ;address of the column code for drawing
  121. draw_row_entry_point dw ?  ;address of the row inline code for drawing
  122. draw_image_offset    dw ?  ;offset in the code segment of the image
  123. ;
  124. queue_item_length equ ($ - queue) ;number of bytes for each item
  125. distance_from_entry_point_to_next_item equ $ - erase_entry_point
  126. distance_from_image_to_next_item equ $ - draw_image_offset
  127. ;
  128.     db    (  (number_of_objects-1) * queue_item_length ) dup(?)
  129. end_of_queue label word
  130. ;
  131. vert_int_modulo_count    dw 0  ;incremented each time a vertical
  132.                   ; interrupt occurs
  133. background_segment    dw ?  ;place to hold the paragraph address
  134.                   ; of the background buffer used to
  135.                   ; erase objects
  136. crtc_base_address    dw ?  ;will hold register address
  137. ;
  138. old_int10_offset    dw ?  ;place to store the vector contents
  139. old_int10_segment    dw ?  ; so they can be restored when finished
  140. ;
  141. old_int_mask        db ?  ;place to store the mask register's
  142.                   ; contents so it can be restored
  143. ;
  144. true    equ    1  ;used for flag values
  145. false    equ    0  ;
  146. ;
  147. need_to_draw_something_flag db false ;true if a change needs to be
  148.                      ; made to any of the objects'
  149.                      ; screen images
  150. ;
  151. screen_buffer_paragraph_adr equ 0b800h
  152. ;
  153. ;
  154. initialize proc near
  155.     cld                   ;count up
  156.     push    ds               ;
  157.     mov    cs:[background_segment],ax ;store background adr
  158.     mov    ax,cs               ;make data segment
  159.     mov    ds,ax               ; same as code segment
  160.                        ; since that is where data
  161.     mov    es,ax               ; used by this routine is
  162.     mov    di,offset queue        ;turn off all objects
  163.     mov    cx,(number_of_objects * queue_item_length)/2
  164.     mov    ax,0ffffh           ;
  165.     rep stosw               ;
  166. ;
  167.     mov    [need_to_draw_something_flag],false ;nothing to draw
  168. if ega
  169.     sub    ax,ax                ;swapping interrupt
  170.     mov    ds,ax                ; vectors with our
  171.     mov    bx,(10*4)            ; interrupt handler
  172.     mov    ax,offset put_objects_on_screen ;our vertical int
  173.     mov    dx,cs                ; handler address
  174.     cli                    ;disable interrupts
  175.     xchg    [bx],ax             ;offset
  176.     xchg    [bx+2],dx            ;segment
  177.     mov    cs:[old_int10_offset],ax    ;save old value so we
  178.     mov    cs:[old_int10_segment],dx    ; can restore it upon
  179. ;                        ; termination
  180.     mov    ax,bios_data_segment        ;find the register
  181.     mov    ds,ax                ; address
  182.     assume    ds:bios_data_segment        ;
  183.     mov    dx,[bios_crtc_base_address]    ;
  184.     mov    cs:[crtc_base_address],dx    ;save it in code seg
  185.     mov    al,11h                ;select vertical
  186.     out    dx,al                ; retrace end register
  187.     mov    al,04h                ; and flip it off
  188.     inc    dx                ;
  189.     out    dx,al                ;
  190.     mov    al,14h                ; then flip it on
  191.     out    dx,al                ;
  192. ;
  193.     in    al,21h                ;enable IRQ2
  194.     mov    cs:[old_int_mask],al        ; save old value
  195.     and    al,not 4            ;
  196.     out    21h,al                ;
  197. ;
  198.     sti                    ;enable interrupts
  199. endif
  200.     pop    ds                ;restore data segment
  201.     ret
  202. initialize endp
  203. ;
  204. terminate    proc    near   ;only needs to be used when assembled
  205. if ega                   ; for use on an EGA
  206.     mov    dx,[crtc_base_address]
  207.     mov    al,11h
  208.     out    dx,al
  209.     inc    dx
  210.     mov    al,24h           ;bit 5 high to disable, bit 4 low to
  211.     out    dx,al           ; clear vertical interrupt
  212.     push    ds
  213.     sub    ax,ax              ;restore original interrupt
  214.     mov    ds,ax              ; 10 vector
  215.     mov    bx,(10*4)          ;
  216.     mov    ax,cs:[old_int10_offset]  ;
  217.     mov    dx,cs:[old_int10_segment] ;
  218.     cli                  ;make sure interrupt
  219.     mov    [bx],ax           ; doesn't occur while
  220.     mov    [bx+2],dx          ; there is an inconsistant
  221.                       ; vector/mask
  222.     mov    bl,cs:[old_int_mask]      ;restore IRQ2 mask bit
  223.     and    bl,4              ; to state it had when
  224.     in    al,21h              ; Initialize was called
  225.     and    al,not 4          ;
  226.     or    al,bl              ;
  227.     out    21h,al              ;
  228.     sti
  229.     pop    ds
  230. endif
  231.     ret
  232. terminate endp
  233. ;
  234. object_services proc near
  235.     cld            ;
  236.     push    es        ;save the registers used
  237.     pus